/*
 * Author: Johan Kristins
 *	
 */
#include "../Game/Context.h"
#include "glWindow.h"
#include <tchar.h>

//namespace NEON
//{
	glWindow::glWindow()
	{

	};

	glWindow::~glWindow()
	{

	}

	bool glWindow::Init(const char * title, unsigned int x, unsigned int y, unsigned int width, unsigned int height)
	{
		hDC = (HDC)0;
		// register the window class
		static char s_acWindowClass[] = "NEON 0.1";
		WNDCLASS wc;
		wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
		wc.lpfnWndProc = (WNDPROC)WndProc;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = GetModuleHandle(NULL);
		wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
		wc.hCursor = LoadCursor(NULL, IDC_ARROW);
		//wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
		wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
		wc.lpszClassName = "NEON";
		wc.lpszMenuName = NULL;
		RegisterClass(&wc);

		// Require the window to have the specified client area
		RECT kRect = {0, 0, width-1, height-1};
		AdjustWindowRect(&kRect, WS_OVERLAPPEDWINDOW, false);

		// Create the application window
		//char s_acWindowTitle[] = title.c_str();
		int iWidth = kRect.right - kRect.left + 1;
		int iHeight = kRect.bottom - kRect.top + 1;
		hWnd = CreateWindow("NEON", 
								 title, 
								 WS_OVERLAPPEDWINDOW,
								 x,
								 y,
								 iWidth,
								 iHeight,
								 (HWND)0,
								 (HMENU)0,
								 wc.hInstance,
								 NULL);

		// Create a window for rendering
		hDC = GetDC(hWnd);

		// Select format for drawing surface
		PIXELFORMATDESCRIPTOR kPFD;
		memset(&kPFD, 0, sizeof(PIXELFORMATDESCRIPTOR));
		kPFD.nSize = sizeof(PIXELFORMATDESCRIPTOR);
		kPFD.nVersion = 1;
		kPFD.dwFlags =
			PFD_DRAW_TO_WINDOW |
			PFD_SUPPORT_OPENGL |
			PFD_GENERIC_ACCELERATED |
			PFD_DOUBLEBUFFER;
		kPFD.iPixelType = PFD_TYPE_RGBA;
		kPFD.cColorBits = 24;
		kPFD.cDepthBits = 16;
		kPFD.cStencilBits = 8;

		int iPixelFormat = ChoosePixelFormat(hDC, &kPFD);
		if (iPixelFormat == 0)
		{
			ReleaseDC(hWnd, hDC);
			return false;
		}

		bool bSucces = SetPixelFormat(hDC, iPixelFormat, &kPFD);
		if (!bSucces)
		{
			ReleaseDC(hWnd, hDC);
			return false;
		}

		// Create openGL context
		hWindowRC = wglCreateContext(hDC);
		if (!hWindowRC)
		{
			ReleaseDC(hWnd, hDC);
			return false;
		}

		bSucces = wglMakeCurrent(hDC, hWindowRC);
		if (!bSucces)
		{
			wglDeleteContext(hWindowRC);
			ReleaseDC(hWnd, hDC);
			return false;
		}

		ShowWindow(hWnd, SW_SHOW);
		UpdateWindow(hWnd);
		SetFocus(hWnd);

		return true;
	};

	bool glWindow::MessagePump()
	{
		static MSG msg;

		while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT || msg.message == WM_DESTROY)
			{
				return false;
			}
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		return true;
	};

	LRESULT CALLBACK glWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
		switch(uMsg) {
			if(TRUE/*m_InputHandler*/) {
				// KEYBOARD
				case WM_KEYDOWN:
					Context::GetHandle()->m_pGameLogic->OnKeyDown((char)wParam);
					break;
				case WM_KEYUP:
					//m_InputHandler->OnKeyUp(wParam);
					break;
				case WM_CHAR:
					//m_InputHandler->OnCharacter(wParam);
					break;
					// MOUSE
				case WM_MOUSEMOVE:
					//m_InputHandler->OnMouseMove(LOWORD(lParam), HIWORD(lParam), wParam);
					break;
				case WM_LBUTTONDBLCLK:
					//m_InputHandler->OnMouseDoubleClick(LOWORD(lParam), HIWORD(lParam), wParam);
					break;
				case WM_LBUTTONDOWN:
					//m_InputHandler->OnMouseButtonDown(LOWORD(lParam), HIWORD(lParam), 0);
					break;
				case WM_RBUTTONDOWN:
					//m_InputHandler->OnMouseButtonDown(LOWORD(lParam), HIWORD(lParam), 1);
					break;
				case WM_LBUTTONUP:
					//m_InputHandler->OnMouseButtonUp(LOWORD(lParam), HIWORD(lParam), 0);
					break;
				case WM_RBUTTONUP:
					//m_InputHandler->OnMouseButtonUp(LOWORD(lParam), HIWORD(lParam), 1);
					break;
					//case WM_MOUSEHWHEEL:
					//	m_InputHandler->OnMouseWheel(LOWORD(lParam), HIWORD(lParam), -1);
					//	break;
			}
			// OTHER
			case WM_SIZE:
				//m_InputHandler->OnResize(LOWORD(lParam), HIWORD(lParam));
				break;
			case WM_CLOSE:
				PostQuitMessage(0);
				break;
		}
		return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
	};

	void glWindow::Exit()
	{
		wglDeleteContext(hWindowRC);
		ReleaseDC(hWnd, hDC);
	};
//};